package cn.dgut.training.controller;


import cn.dgut.training.annotation.RequiresPermissionsDesc;
import cn.dgut.training.entity.Admin;
import cn.dgut.training.entity.Permission;
import cn.dgut.training.entity.Role;
import cn.dgut.training.service.impl.AdminServiceImpl;
import cn.dgut.training.service.impl.PermissionServiceImpl;
import cn.dgut.training.service.impl.RoleServiceImpl;
import cn.dgut.training.util.JacksonUtil;
import cn.dgut.training.util.PermissionUtil;
import cn.dgut.training.util.UPermission;
import cn.dgut.training.vo.CommonResponse;
import cn.dgut.training.vo.PermVO;
import cn.dgut.training.vo.pageVO.PageVO;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;

@RestController
@RequestMapping("/role")
public class RoleController {

        @Resource
        private RoleServiceImpl roleService;
        @Resource
        private PermissionServiceImpl permissionService;
        @Resource
        private AdminServiceImpl adminService;

        @RequiresPermissions("admin:role:list")
        @RequiresPermissionsDesc(menu = {"系统管理", "角色管理"}, button = "角色查询")
        @GetMapping("/list")
        public CommonResponse list(String name) {

            return CommonResponse.success( roleService.querySelective(name));
        }

        @GetMapping("/options")
        public CommonResponse options() {
            List<Role> roleList = roleService.queryAll();

            List<Map<String, Object>> options = new ArrayList<>(roleList.size());
            for (Role role : roleList) {
                Map<String, Object> option = new HashMap<>(2);
                option.put("value", role.getId());
                option.put("label", role.getName());
                options.add(option);
            }
                PageVO pageVO=new PageVO("通用",options);

            return CommonResponse.success(pageVO);
        }

        @RequiresPermissions("admin:role:read")
        @RequiresPermissionsDesc(menu = {"系统管理", "角色管理"}, button = "角色详情")
        @GetMapping("/read")
        public CommonResponse read(@NotNull Integer id) {
            Role role = roleService.getById(id);
            return CommonResponse.success(role);
        }


        private CommonResponse validate(Role role) {
            String name = role.getName();
            if (StringUtils.isEmpty(name)) {
                return CommonResponse.fail(401, "参数不对");
            }

            return null;
        }

        @RequiresPermissions("admin:role:create")
        @RequiresPermissionsDesc(menu = {"系统管理", "角色管理"}, button = "角色添加")
        @PostMapping("/create")
        public CommonResponse create(@RequestBody Role role) {
            Object error = validate(role);
            if (error != null) {
                    return CommonResponse.success(error);
            }

            if (roleService.checkExist(role.getName())) {
                return CommonResponse.fail(604, "角色已经存在");
            }

            roleService.add(role);

            return CommonResponse.success(role);
        }

        @RequiresPermissions("admin:role:update")
        @RequiresPermissionsDesc(menu = {"系统管理", "角色管理"}, button = "角色编辑")
        @PostMapping("/update")
        public CommonResponse update(@RequestBody Role role) {
            Object error = validate(role);
            if (error != null) {
                return CommonResponse.success(error);
            }

            roleService.updateById(role);
            return CommonResponse.message();
        }

        @RequiresPermissions("admin:role:delete")
        @RequiresPermissionsDesc(menu = {"系统管理", "角色管理"}, button = "角色删除")
        @PostMapping("/delete")
        public CommonResponse delete(@RequestBody Role role) {
            Long id = role.getId();
            if (id == null) {
                return CommonResponse.fail(401, "参数不对");
            }

            // 如果当前角色所对应管理员仍存在，则拒绝删除角色。
            List<Admin> adminList = adminService.all();
            for (Admin admin : adminList) {
                Integer[] roleIds = admin.getArrRoleIds();
                for (Integer roleId : roleIds) {
                    if (id.equals(roleId)) {
                        return CommonResponse.fail(642, "当前角色存在管理员，不能删除");
                    }
                }
            }

            roleService.removeById(id);
            return CommonResponse.message();
        }


        @Autowired
        private ApplicationContext context;
        private List<PermVO> systemPermissions = null;
        private Set<String> systemPermissionsString = null;

        private List<PermVO> getSystemPermissions() {
            final String basicPackage = "cn.dgut.training";
            if (systemPermissions == null) {
                List<UPermission> uPermissions = PermissionUtil.listPermission(context, basicPackage);
                systemPermissions = PermissionUtil.listPermVo(uPermissions);
                systemPermissionsString = PermissionUtil.listPermissionString(uPermissions);
            }
            return systemPermissions;
        }

        private Set<String> getAssignedPermissions(Integer roleId) {
            // 这里需要注意的是，如果存在超级权限*，那么这里需要转化成当前所有系统权限。
            // 之所以这么做，是因为前端不能识别超级权限，所以这里需要转换一下。
            Set<String> assignedPermissions = null;
            if (permissionService.checkSuperPermission(roleId)) {
                getSystemPermissions();
                assignedPermissions = systemPermissionsString;
            } else {
                assignedPermissions = permissionService.queryByRoleId(roleId);
            }

            return assignedPermissions;
        }

        /**
         * 管理员的权限情况
         *
         * @return 系统所有权限列表和管理员已分配权限
         */
        @RequiresPermissions("admin:role:permission:get")
        @RequiresPermissionsDesc(menu = {"系统管理", "角色管理"}, button = "权限详情")
        @GetMapping("/permissions")
        public CommonResponse getPermissions(Integer roleId) {
            List<PermVO> systemPermissions = getSystemPermissions();
            Set<String> assignedPermissions = getAssignedPermissions(roleId);

            Map<String, Object> data = new HashMap<>();
            data.put("systemPermissions", systemPermissions);
            data.put("assignedPermissions", assignedPermissions);
            return CommonResponse.success(data);
        }


        /**
         * 更新管理员的权限
         *
         * @param body
         * @return
         */
        @RequiresPermissions("admin:role:permission:update")
        @RequiresPermissionsDesc(menu = {"系统管理", "角色管理"}, button = "权限变更")
        @PostMapping("/permissions")
        public CommonResponse updatePermissions(@RequestBody String body) {
            Integer roleId = JacksonUtil.parseInteger(body, "roleId");
            List<String> permissions = JacksonUtil.parseStringList(body, "permissions");
            if (roleId == null || permissions == null) {
                return CommonResponse.fail(401, "参数不对");
        }

            // 如果修改的角色是超级权限，则拒绝修改。
            if (permissionService.checkSuperPermission(roleId)) {
                return CommonResponse.fail(641, "当前角色的超级权限不能变更");
            }

            // 先删除旧的权限，再更新新的权限
            permissionService.removeById(roleId);
            for (String permission : permissions) {
                Permission Permission = new Permission();
                Permission.setRoleId(roleId);
                Permission.setPermission(permission);
                permissionService.add(Permission);
            }
            return CommonResponse.message();
        }

}
